import { IconFormatType } from '../../../types/interfaces'
import { StringUtils } from '../base/string'

/**
 * SVG 工具类
 */
export class SvgUtils {
  /**
   * 将 SVG 字符串转换为 DataURL
   * @param svg 原始 SVG 字符串
   * @param encoding 编码类型：'uri'（默认）或 'base64'
   * @returns data:image/svg+xml... 格式的URL
   */
  static svgToDataURL(
    svg: string,
    encoding: 'uri' | 'base64' = 'uri',
  ): string {
    // 编码处理
    switch (encoding) {
      case 'uri':
        return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`
      case 'base64':
        return `data:image/svg+xml;base64,${btoa(svg)}`
      default:
        throw new Error(`Unsupported encoding type: ${encoding}`)
    }
  }

  /**
   * 统一格式化 SVG 图标
   * @param svg - 原始 SVG 字符串
   * @param format - 输出格式类型
   * @returns 格式化后的字符串
   */
  static formatSvgIcon(
    svg: string,
    format: IconFormatType = IconFormatType.cssUrl,
  ): string {
    const optimized = svg
      .replace(/\s+/g, ' ')
      .replace(/>\s+</g, '><')
      .trim()

    switch (format) {
      case IconFormatType.svg:
        return optimized

      case IconFormatType.dataUrl:
        return this.svgToDataURL(optimized)

      case IconFormatType.cssUrl:
        return `url("${this.svgToDataURL(optimized)}")`

      default:
        throw new Error(`Unsupported format: ${format}`)
    }
  }

  /**
   * 清洗阿里 SVG 图标字符串
   * @param svgStr 原始 SVG 字符串
   * @returns 清洗后的 SVG 字符串
   */
  static cleanAliSvg(svgStr: string): string {
    // 需要移除的属性正则表达式列表
    const attributePatterns: RegExp[] = [
      /\s*t="[^"]+"/, // t属性
      /\s*class="[^"]+"/, // class属性
      /\s*version="[^"]+"/, // version属性
      /\s*p-id="\d+"/, // p-id属性
      /\s*data-spm-anchor-id="[^"]+"/, // data-spm锚点ID
      /\s*data-spm="[^"]+"/, // 其他可能的spm属性
      /\s*spm-anchor-id="[^"]+"/, // 其他可能的spm变体
    ]

    // 1. 移除不需要的属性
    let cleaned = svgStr
    attributePatterns.forEach((regex) => {
      cleaned = cleaned.replace(regex, '')
    })

    // 2. 转换标签闭合方式
    cleaned = cleaned.replace(/><\/path>/g, '/>')

    // 3. 双引号转单引号（处理属性和标签）
    cleaned = cleaned
      .replace(/"([^"]*)"/g, '\'$1\'') // 属性值转换
      .replace(/<([^>]*)>/g, (match) => {
        // 处理自闭合标签的引号（如 <path d='...'/>）
        return match.replace(/"/g, '\'')
      })

    // 4. 处理特殊情况（如JSX中的属性）
    cleaned = cleaned.replace(/\{\s*'([^']+)'\s*\}/g, '"$1"')

    // 5. 标准化空格和换行
    cleaned = cleaned
      .replace(/\s+/g, ' ') // 多个空格转单个
      .replace(/>\s+</g, '><') // 移除标签间空格
      .trim()

    return cleaned
  }

  /**
   * 从 SVG 创建<img>元素HTML
   * @param svg SVG 字符串或已格式化的 DataURL
   * @param alt 替代文本（默认空）
   * @param className CSS 类名（可选）
   * @param attributes 额外 HTML 属性（可选）
   * @returns 完整的<img>标签HTML
   */
  static createSvgImage(
    svg: string,
    alt: string = '',
    className?: string,
    attributes: Record<string, string> = {},
  ): string {
    // 自动检测输入格式
    const isDataUrl = svg.startsWith('data:image/svg+xml')
    const src = isDataUrl ? svg : `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`

    // 构建属性字符串
    const attrs = Object.entries({
      src,
      alt,
      ...(className && { class: className }),
      ...attributes,
    }).map(([key, val]) => `${key}="${StringUtils.escapeHtml(val)}"`).join(' ')

    // noinspection HtmlRequiredAltAttribute
    return `<img ${attrs}>`
  }
}
